package com.hhq.demo.mvc;

import javax.xml.ws.Response;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author HHQ
 * @date 2021年12月10日
 * 中央处理器，包含了大量网址与方法的对应关系
 */
public class HandlerMapping {
    /**
     * 存储网址与方法关系的容器
     */
    private static Map<String, MVCConfig> data = new HashMap<>();

    /**
     * 根据uri获取对应的方法对象
     *
     * @param uri uri
     * @return MVCConfig对象
     */
    public static MVCConfig get(String uri) {
        return data.get(uri);
    }

    /**
     * 加载配置文件
     *
     * @param is 配置文件的输入流
     */
    public static void load(InputStream is) {
        Properties properties = new Properties();
        try {
            //加载配置文件
            properties.load(is);
            //获取配置文件的内容，类的全路径名
            Collection<Object> classNames = properties.values();
            for (Object classname : classNames) {
                //通过反射获取该类的字节码对象
                Class cla = Class.forName((String) classname);
                //创建当前类对象
                Object obj = cla.newInstance();
                //获取该类的所有方法
                Method[] methods = cla.getMethods();
                for (Method method : methods) {
                    //获取每一个方法的注解
                    Annotation[] annotations = method.getAnnotations();
                    for (Annotation annotation : annotations) {
                        if (annotation instanceof ResponseBody) {
                            //如果当前注解为ResponseBody，则需要将返回值以TEXT方式 返回
                            MVCConfig mapping = new MVCConfig(obj, method, ResponseType.TEXT);
                            //存储
                            Object o = data.put(((ResponseBody) annotation).value(), mapping);
                            //判断当前请求地址是否已经存在
                            if (o != null) {
                                throw new RuntimeException("请求地址重复" + ((ResponseBody) annotation).value());
                            }
                        } else if (annotation instanceof ResponseView) {
                            //如果当前注解为ResponseView，则直接重定向
                            MVCConfig mapping = new MVCConfig(obj, method, ResponseType.VIEW);
                            //存储
                            Object o = data.put(((ResponseView) annotation).value(), mapping);
                            //判断当前请求地址是否已经存在
                            if (o != null) {
                                throw new RuntimeException("请求地址重复" + ((ResponseView) annotation).value());
                            }
                        }
                    }
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * @author HHQ
     * @date 2021年12月10日
     * 映射对象，每一个对象封装了一个方法，用于处理请求
     */
    public static class MVCConfig {
        private Object obj;
        private Method method;
        private ResponseType type;

        public Object getObj() {
            return obj;
        }

        public void setObj(Object obj) {
            this.obj = obj;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public ResponseType getType() {
            return type;
        }

        public void setType(ResponseType type) {
            this.type = type;
        }

        public MVCConfig() {
        }

        public MVCConfig(Object obj, Method method, ResponseType type) {
            this.obj = obj;
            this.method = method;
            this.type = type;
        }
    }
}
